Day 17 稍微認識interface進階一點點的用法
extends
關鍵字是用來擴充一個 interface
描述的屬性,例如:
interface Person {
first_name: string;
last_name: string;
birth_year: number;
}
interface SuperHero extends Person {
title: string;
ability: string;
}
const Kent: SuperHero = ('Clark', 'Kent', 1938, 'superman', 'fly');
範例的意思是,因為SuperHero也擁有Person所描述的first_name、last_name屬性,因此使用 extends
直接從延伸Person擁有的屬性。
這樣做的好處有幾個,假設SuperHero包含所有Person擁有的屬性,並且Person有十幾、二十個SuperHero也擁有的屬性:
title
、ability
寫進Person,可能會影響指定Person為型別的物件 ─ 因為這個範例的邏輯是,SuperHero是Person的子集,將Person指定為型別的物件應該都不會有SuperHero的title
、ability
屬性。由此可知,SuperHero應該用extends
去延伸、重複利用Person的屬性;extends
延伸Person的所有屬性,SuperHero就不用在自己的 interface
重寫一次這麼多個屬性;extends
Person的interface,而不用一個一個interface去修改屬性型別;另外,一個 interface
也能使用 ,
來 extends
好幾個 interface
s。
假設Clark Kent平常不當超人的時候,只是一家公司的普通員工,所以他會擁有某家公司的所有員工(Employee)屬性:
interface Person {
first_name: string;
last_name: string;
birth_year: number;
}
interface Employee {
eid: number;
department: string;
director: number;
job: string;
salary: number;
}
interface SuperHero extends Person, Employee {
title: string;
ability: string;
}
Day 15講到類別(class)的時候有提到「類別可以用implements
關鍵字去實作interface的方法」。
意思是,interface只會事先定義類別所有可能會擁有的方法和屬性型別(即class表面上應該長什麼樣子),如下的Shape介面;而class則是能用 implements
關鍵字實際寫出方法的內容。
舉一個比較簡單一點的例子,這裡讓Rectangle類別 implements
Shape介面:
interface Shape {
width: number;
height: number;
getArea() => number;
}
class Rectangle implements Shape {
private width: number;
private height: number;
constructor(width: number, height: number){
this.width = width;
this.height = height;
}
getArea() {
return this.width * this.height;
};
}
有個有趣的事情是,interface也是能夠extends
一個類別,但是只有這個被extends的類別和其子類別可以implemetns
這個interface,否則就會出錯。
接續前一個例子,這裡刻意定義了一個Triangle類別要實作的interface:
interface TriangleShape extends Rectangle {
angles: [number, number, number];
}
class Triangle extends Rectangle implements TriangleShape {
private width: number;
private height: number;
private angles: [number, number, number];
constructor(width: number, height: number, angle: [number, number, number]){
super(width, height);
this.angle = angle;
}
getArea(){
return this.width * this.height / 2;
}
}
class Circle implements TriangleShape {}; // error
在這個範例裡,TriangleShape extends
Rectangle類別,但是Circle類別不屬於Rectangle的子類別,所以沒辦法實作TriangleShape這個interface。
參考資料
TypeScript: JavaScript With Syntax For Types
TypeScript Tutorial